﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Portal.FileSystemData;
using System.Web.UI.HtmlControls;
using System.IO;

namespace Portal.Modules.ImageBrowser
{
  /// <summary>
  /// Represents the state when the Picture ist shown.
  /// </summary>
  public partial class StateShowPicture : Portal.StateBase.ModuleState
  {
    DataAccessor _dataAccessor;
    CacheAgent _cacheAgent;

    protected void Page_Load(object sender, EventArgs e)
    {
      _dataAccessor = new DataAccessor(Document);
      _cacheAgent = new CacheAgent(_dataAccessor);

      if (TransitionArgument != null)
      {
        ViewState["File"] = TransitionArgument;
      }
    }

    protected override void OnPreRender(EventArgs e)
    {
      base.OnPreRender(e);

      object file = ViewState["File"];
      if (file == null)
        throw new InvalidOperationException("Current file unknown!");

      string filePath = file as string;
      FileWrapper previousFile;
      FileWrapper nextFile;
      FileWrapper fileWrap = _dataAccessor.RootDirectory.GetFileWithSiblings(filePath, out previousFile, out nextFile);
      if (fileWrap == null)
        throw new InvalidOperationException("Could not find file!");

      // If the Preview is rendered with a shadow, then make sure the files exists.
      if (_dataAccessor.Config.PreviewCfg.HasShadow)
      {
        string shadowDir = _cacheAgent.PreviewShadowPath;
        if (!File.Exists(Path.Combine(shadowDir, "tr.jpg")))
        {
          _cacheAgent.UpdatePreviewShadowParts();
        }
      }
      // Create the controls for this file.
      _imgPosition.Controls.Add(RenderImagePreview(fileWrap, nextFile));


      _description.Text = fileWrap.Description;

      // Configure the navigation buttons.
      _previousBtn.Visible = (previousFile != null);
      _nextBtn.Visible = (nextFile != null);

      if (previousFile != null)
        _previousBtn.CommandArgument = previousFile.VirtualPath;
      if (nextFile != null)
        _nextBtn.CommandArgument = nextFile.VirtualPath; 

      // Stop Slideshow if its the last image.
      if (nextFile == null && _autoPlayTmr.Enabled)
        EnableAutoPlay(false);
      _autoPlay.Visible = nextFile != null;
     }


    /// <summary>
    ///  This creates the Preview of the image with the optional shadow.
    /// </summary>
    /// <param name="data">The image to render</param>
    /// <param name="nextFile">The file to preload after the image is loaded (cache for the next picture)</param>
    /// <returns>The Control which contains all the elements</returns>
    public Control RenderImagePreview(FileWrapper data, FileWrapper nextFile)
    {
      string shadowDirVirtual = _cacheAgent.PreviewVirtualShadowPath;
      string versionExtension = "?v=" + _dataAccessor.Config.ConfigVersion.ToString();

      int shadowWidth = _dataAccessor.Config.PreviewCfg.ShadowWidth;

      HyperLink lnk = new HyperLink();
      lnk.NavigateUrl = VirtualPathUtility.Combine(_dataAccessor.Config.PictureVirtualPath, data.VirtualPath);
      lnk.Target = "_blank";

      var img = new System.Web.UI.WebControls.Image();
      img.ImageUrl = _cacheAgent.GetPreviewImageUrl(data);
      lnk.Controls.Add(img);

      Control ResultCtrl = null;
      if (_dataAccessor.Config.PreviewCfg.HasShadow)
      {
        img.Style["display"] = "block";

        // Get the size.
        System.Drawing.Image imgData = System.Drawing.Image.FromFile(_cacheAgent.GetPreviewCachePath(data));
        int imageHeight = imgData.Height;
        int imageWidth = imgData.Width;
        imgData.Dispose();

        HtmlGenericControl container = new HtmlGenericControl("div");
        container.Style["width"] = (imageWidth + shadowWidth).ToString() + "px";
        container.Style["height"] = (imageHeight + shadowWidth).ToString() + "px";
        container.Style["margin"] = "auto"; // horizontal alignment: center.

        // Add Image.
        lnk.Style["float"] = "left";
        container.Controls.Add(lnk);

        // Right Side Shadow.
        HtmlGenericControl rightBorder = new HtmlGenericControl("div");
        rightBorder.Style["width"] = shadowWidth.ToString() + "px";
        rightBorder.Style["height"] = imageHeight.ToString() + "px";
        rightBorder.Style["float"] = "right";
        rightBorder.Style["background-image"] = "url(" + VirtualPathUtility.Combine(shadowDirVirtual, "r.jpg") + versionExtension + ")";
        rightBorder.Style["background-repeat"] = "top right repeat-y";
        container.Controls.Add(rightBorder);

        // Top Right Corner Shadow.
        System.Web.UI.WebControls.Image topRightCorner = new System.Web.UI.WebControls.Image();
        topRightCorner.ImageUrl = VirtualPathUtility.Combine(shadowDirVirtual, "tr.jpg")+ versionExtension;
        rightBorder.Controls.Add(topRightCorner);

        // Bottom Shadow.
        HtmlGenericControl bottomBorder = new HtmlGenericControl("div");
        bottomBorder.Style["width"] = (imageWidth + shadowWidth).ToString() + "px";
        bottomBorder.Style["height"] = shadowWidth.ToString() + "px";
        bottomBorder.Style["float"] =  "left";
        bottomBorder.Style["background-image"] = "url(" + VirtualPathUtility.Combine(shadowDirVirtual, "b.jpg") + versionExtension + ")";
        bottomBorder.Style["background-repeat"] = "top right repeat-x";
        container.Controls.Add(bottomBorder);

        // Bottom Left Corner Shadow.
        System.Web.UI.WebControls.Image bottomLeftCorner = new System.Web.UI.WebControls.Image();
        bottomLeftCorner.ImageUrl = VirtualPathUtility.Combine(shadowDirVirtual, "bl.jpg") + versionExtension;
        bottomLeftCorner.Style["float"] = "left";
        bottomBorder.Controls.Add(bottomLeftCorner);

        // Bottom Right Corner Shadow.
        System.Web.UI.WebControls.Image bottomRightCorner = new System.Web.UI.WebControls.Image();
        bottomRightCorner.ImageUrl = VirtualPathUtility.Combine(shadowDirVirtual, "br.jpg") + versionExtension;
        bottomRightCorner.Style["float"] = "right";
        bottomBorder.Controls.Add(bottomRightCorner);

        ResultCtrl = container;
      }
      else
        ResultCtrl = lnk;

      // Add the caching code for the next picture.
      if(nextFile != null)
      {
        // Register the Script for the event when the main Image is loaded.
        string path = ResolveUrl(_cacheAgent.GetPreviewVirtualCachePath(nextFile, true));
        string jsCode = "img = new Image(); img.src='" + path + "';";
        img.Attributes.Add("onload", jsCode);
      }

      return ResultCtrl;
    }


    protected void OnChangeFile(object sender, CommandEventArgs e)
    {
      ViewState["File"] = e.CommandArgument;
      EnableAutoPlay(false);
    }

    protected void OnBackToThumbnails(object sender, EventArgs e)
    {
      ProcessEvent((int)StateEvent.Back, ViewState["File"]);
    }


    protected void OnAutoPlay(object sender, EventArgs e)
    {
      EnableAutoPlay(!_autoPlayTmr.Enabled);
    }

    protected void EnableAutoPlay(bool enable)
    {
      if (enable)
      {
        // Start Autoplaying.
        SwitchPicture();
        _autoPlayTmr.Enabled = true;
        _autoPlay.ImageUrl = "~/PortalImages/Pause.gif";
        _autoPlay.TooltipLanguageRef = "autoPlayTooltipPause";
        _autoPlay.AlternateTextLanguageRef = "autoPlayPause";
      }
      else
      {
        // Stop Autoplaying.
        _autoPlayTmr.Enabled = false;
        _autoPlay.ImageUrl = "~/PortalImages/Play.gif";
        _autoPlay.TooltipLanguageRef = "autoPlayTooltip";
        _autoPlay.AlternateTextLanguageRef = "autoPlay";
      }
    }

    protected void OnAutoPlaySwitch(object sender, EventArgs e)
    {
      SwitchPicture();
    }

    protected void SwitchPicture()
    {
      object file = ViewState["File"];
      if (file == null)
        throw new InvalidOperationException("Current file unknown!");

      string filePath = file as string;
      FileWrapper previousFile;
      FileWrapper nextFile;
      _dataAccessor.RootDirectory.GetFileWithSiblings(filePath, out previousFile, out nextFile);
      if (nextFile != null)
      {
        ViewState["File"] = nextFile.VirtualPath;
      }
      else
        EnableAutoPlay(false);
    }
  }
}
